package com.zhanglu.fun.services.chatroom.security;

import com.zhanglu.fun.tookit.json.JsonTools;
import com.zhanglu.fun.tookit.jwt.AuthenticationUser;
import com.zhanglu.fun.tookit.jwt.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

@Slf4j
@Component
public class PreAuthFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        Cookie[] cookieArr =  httpServletRequest.getCookies();
        if (null == cookieArr || cookieArr.length <= 0) {
            log.debug("Cookie was not found，this url:{} is permit all!", httpServletRequest.getRequestURL());
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }

        String token = Arrays.stream(cookieArr).filter(cookie -> JwtUtil.COOKIE_AUTH.equalsIgnoreCase(cookie.getName()))
                .map(Cookie::getValue).findFirst().orElse(null);
        log.debug("doFilter get token from cookie is {}", token);
        if(StringUtils.isBlank(token)){
            log.debug("token was not found，this url:{} is permit all!", httpServletRequest.getRequestURL());
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }
        AuthenticationUser authenticationUser = JwtUtil.parserToken(token);
        log.debug("the user info is {}", JsonTools.showJSONStringFormat(authenticationUser));

        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(authenticationUser, token, authenticationUser.getAuths());
        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
        logger.debug("authenticated user " + authenticationUser.getUsername() + ", setting security context");
        SecurityContextHolder.getContext().setAuthentication(authentication);

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
